package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.BizBarcodeMapper;
import com.ruoyi.system.mapper.BizPurchaseOrderMapper;
import com.ruoyi.system.domain.BizBarcode;
import com.ruoyi.system.domain.BizPurchaseOrder;
import com.ruoyi.system.domain.BizPurchaseOrderItem;
import com.ruoyi.system.domain.dto.GenerateBarcodeRequest;
import com.ruoyi.system.service.IBizBarcodeService;

@Service
public class BizBarcodeServiceImpl implements IBizBarcodeService 
{
    @Autowired
    private BizBarcodeMapper bizBarcodeMapper;

    @Autowired
    private BizPurchaseOrderMapper bizPurchaseOrderMapper;

    @Override
    public BizBarcode selectBizBarcodeByBarcodeId(Long barcodeId)
    {
        return bizBarcodeMapper.selectBizBarcodeByBarcodeId(barcodeId);
    }

    @Override
    public List<BizBarcode> selectBizBarcodeList(BizBarcode bizBarcode)
    {
        return bizBarcodeMapper.selectBizBarcodeList(bizBarcode);
    }

    @Override
    public int insertBizBarcode(BizBarcode bizBarcode)
    {
        return bizBarcodeMapper.insertBizBarcode(bizBarcode);
    }

    @Override
    public int updateBizBarcode(BizBarcode bizBarcode)
    {
        return bizBarcodeMapper.updateBizBarcode(bizBarcode);
    }

    @Override
    public int deleteBizBarcodeByBarcodeIds(Long[] barcodeIds)
    {
        return bizBarcodeMapper.deleteBizBarcodeByBarcodeIds(barcodeIds);
    }

    @Override
    public int deleteBizBarcodeByBarcodeId(Long barcodeId)
    {
        return bizBarcodeMapper.deleteBizBarcodeByBarcodeId(barcodeId);
    }

    /**
     * 生成箱码并更新采购订单明细数量
     */
    @Transactional
    @Override
    public int generateBarcodes(GenerateBarcodeRequest request) {
        if (request == null) {
            throw new ServiceException("参数不能为空");
        }
        Long itemId = request.getItemId();
        BigDecimal encodeQuantity = defaultZero(request.getEncodeQuantity());
        BigDecimal stdPerBox = defaultZero(request.getStdPerBox());
        // 后端根据当天最大值生成批次号：yyyyMMddNNN
        String dateStr = DateUtils.parseDateToStr("yyyyMMdd", DateUtils.getNowDate());
        String maxBatchNo = bizBarcodeMapper.selectMaxBatchNoByDate(dateStr);
        int nextBatchSeq = 1;
        if (StringUtils.isNotEmpty(maxBatchNo) && maxBatchNo.startsWith(dateStr)) {
            String suffix = maxBatchNo.substring(dateStr.length());
            try {
                nextBatchSeq = Integer.parseInt(suffix) + 1;
            } catch (NumberFormatException e) {
                nextBatchSeq = 1;
            }
        }
        String batchNo = dateStr + String.format("%03d", nextBatchSeq);
        // 使控制器能够返回该批次号
        request.setBatchNo(batchNo);

        if (itemId == null) {
            throw new ServiceException("缺少订单明细ID");
        }
        if (encodeQuantity.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("本次打码数量必须大于0");
        }
        if (stdPerBox.compareTo(BigDecimal.ZERO) <= 0) {
            throw new ServiceException("标箱数量必须大于0");
        }

        BizPurchaseOrderItem item = bizPurchaseOrderMapper.selectBizPurchaseOrderItemByItemId(itemId);
        if (item == null) {
            throw new ServiceException("未找到对应采购订单明细");
        }
        BigDecimal orderQty = defaultZero(item.getOrderQuantity());
        BigDecimal barcoded = defaultZero(item.getBarcodedQuantity());
        BigDecimal remaining = orderQty.subtract(barcoded);
        if (encodeQuantity.compareTo(remaining) > 0) {
            throw new ServiceException("本次打码数量超过未打码数量");
        }

        // 取订单头，获取供应商编码
        String supplierCode = null;
        BizPurchaseOrder query = new BizPurchaseOrder();
        query.setOrderNo(item.getOrderNo());
        List<BizPurchaseOrder> orderList = bizPurchaseOrderMapper.selectBizPurchaseOrderList(query);
        if (orderList != null && !orderList.isEmpty()) {
            supplierCode = orderList.get(0).getSupplierCode();
        }

        // 生成当日条码前缀 BCyyyyMMdd（复用上面的 dateStr）
        String barcodePrefix = "BC" + dateStr;
        String maxBarcode = bizBarcodeMapper.selectMaxBarcodeByPrefix(barcodePrefix);
        int nextSeq = 1;
        if (StringUtils.isNotEmpty(maxBarcode) && maxBarcode.startsWith(barcodePrefix)) {
            String suffix = maxBarcode.substring(barcodePrefix.length());
            try {
                nextSeq = Integer.parseInt(suffix) + 1;
            } catch (NumberFormatException e) {
                nextSeq = 1;
            }
        }

        // 计算箱数与每箱装箱数量
        int boxes = encodeQuantity.divide(stdPerBox, 0, java.math.RoundingMode.CEILING).intValue();
        Date now = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();

        List<BizBarcode> toInsert = new ArrayList<>();
        BigDecimal remainingQty = encodeQuantity;
        for (int i = 0; i < boxes; i++) {
            BigDecimal pack = remainingQty.compareTo(stdPerBox) > 0 ? stdPerBox : remainingQty;
            remainingQty = remainingQty.subtract(pack);

            String barcode = barcodePrefix + String.format("%05d", nextSeq++);
            BizBarcode b = new BizBarcode();
            b.setBarcode(barcode);
            b.setBarcodeStatus("GENERATED");
            b.setItemId(item.getItemId());
            b.setOrderNo(item.getOrderNo());
            b.setBatchNo(batchNo);
            b.setInventoryCode(item.getInventoryCode());
            b.setSupplierCode(supplierCode);
            b.setPackQuantity(pack);
            b.setUnitCode(item.getUnitCode());
            // 送货时间优先使用前端传入的发货日期；为空则用当前时间
            Date deliveryTime = request.getDeliveryDate();
            b.setDeliveryTime(deliveryTime != null ? deliveryTime : now);
            // 默认值：是否拒收=0，质检结果=0
            b.setIsRejected("0");
            b.setQualityResult("0");
            b.setCreatedBy(username);
            b.setCreatedTime(now);
            b.setDelFlag("0");
            toInsert.add(b);
        }

        int rows = 0;
        for (BizBarcode b : toInsert) {
            rows += bizBarcodeMapper.insertBizBarcode(b);
        }

        // 更新明细已打码/未打码数量
        BigDecimal newBarcoded = barcoded.add(encodeQuantity);
        BigDecimal newUnbarcoded = orderQty.subtract(newBarcoded);
        bizPurchaseOrderMapper.updateBizPurchaseOrderItemQuantities(
            item.getItemId(), newBarcoded, newUnbarcoded, username, now
        );

        return rows;
    }

    // 新增：获取当日下个批次号，供前端弹窗展示
    @Override
    public String getNextBatchNoForToday() {
        String dateStr = DateUtils.parseDateToStr("yyyyMMdd", DateUtils.getNowDate());
        String maxBatchNo = bizBarcodeMapper.selectMaxBatchNoByDate(dateStr);
        int next = 1;
        if (StringUtils.isNotEmpty(maxBatchNo) && maxBatchNo.startsWith(dateStr)) {
            String suffix = maxBatchNo.substring(dateStr.length());
            try {
                next = Integer.parseInt(suffix) + 1;
            } catch (NumberFormatException e) {
                next = 1;
            }
        }
        return dateStr + String.format("%03d", next);
    }

    private BigDecimal defaultZero(BigDecimal v) {
        return v == null ? BigDecimal.ZERO : v;
    }
}
